package com.snk.back.service.realm;


import com.snk.back.dao.SysMenuDao;
import com.snk.back.dao.SysRoleMenuDao;
import com.snk.back.dao.SysUserDao;
import com.snk.back.dao.SysUserRoleDao;
import com.snk.pojo.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Service
public class ShiroUserRealm  extends AuthorizingRealm {
    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
@Autowired
    private SysMenuDao sysMenuDao;
    /**
     * 负责用户权限信息的获取和封装
     * @param principals
     * @return
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //获取登陆用户
        SysUser user= (SysUser) principals.getPrimaryPrincipal();
        //基于登陆用户查询用户对应的角色Id并校验
        Integer userId=user.getId();
        List<Integer> roleIds=
                sysUserRoleDao.findRoleIdsByUserId(userId);
        if(roleIds==null||roleIds.size()==0)
            throw new AuthorizationException();
        //基于角色id查询菜单id并校验
        List<Integer> menuIds=
                sysRoleMenuDao.findMenuIdsByRoleIds(roleIds);
        if(menuIds==null||menuIds.size()==0)
            throw new AuthorizationException();
        //基于菜单id找到授权标识并校验
        List<String> permissions=
                sysMenuDao.findPermissions(menuIds);
        Set<String> set=new HashSet<>();
        for (String per:permissions){
            if(!StringUtils.isEmpty(per)){
                set.add(per);
            }
        }
        //封装用户权限信息并返回（交给SecurityManager对象）
        SimpleAuthorizationInfo info=
                new SimpleAuthorizationInfo();
        info.setStringPermissions(set);
        return info;
    }

    /**
     * 负责认证信息的获取和封装
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //获取登陆用户信息（用户名--密码）
        UsernamePasswordToken upToken=(UsernamePasswordToken)token;
        String username=upToken.getUsername();
        //基于用户名查询数据库中的用户的对象
        SysUser user=sysUserDao.findUserByUserName(username);
        //检测用户是否存在
        if(user==null)
            throw new UnknownAccountException();
        //检测用户是否被禁用
        if(user.getValid()==0)
            throw new LockedAccountException();
        //封装用户信息并返回结果
        ByteSource credentialsSalt=
                ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info=
                new SimpleAuthenticationInfo(user,//principal（用户身份）
                        user.getPassword(),//credentials（凭证++已加密的密码）访问数据库得到的
                        credentialsSalt,//credentialsSalt（凭证盐）
                        getName());
        return info;
    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher){
        HashedCredentialsMatcher cMatcher=
                new HashedCredentialsMatcher();
        cMatcher.setHashAlgorithmName("MD5");
        super.setCredentialsMatcher(cMatcher);
    }




}
